﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace DAXT
{
    public partial class FormCompareXPOs : Form
    {
        public FormCompareXPOs()
        {
            InitializeComponent();
        }

        #region Event handlers

        private void btnSplitProjects_Click(object sender, EventArgs e)
        {
            lstOnlyInP1.Items.Clear();
            lstOnlyInP2.Items.Clear();
            lstDifferent.Items.Clear();

            if (!File.Exists(txtFirstProject.Text))
            {
                MessageBox.Show("You must select an .xpo file for the first project.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (!File.Exists(txtSecondProject.Text))
            {
                MessageBox.Show("You must select an .xpo file for the second project.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            if (!Directory.Exists(txtOutputFolder.Text))
            {
                MessageBox.Show("You must select an output folder.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            try
            {
                this.Cursor = Cursors.WaitCursor;

                this.SplitProjectFile(txtFirstProject.Text, txtProject1Name.Text);
                this.SplitProjectFile(txtSecondProject.Text, txtProject2Name.Text);

                this.Cursor = Cursors.Default;

                MessageBox.Show("Splitting the project files successfully completed", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception ex)
            {
                this.Cursor = Cursors.Default;

                MessageBox.Show(ex.Message, "Warning", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void btnCompare_Click(object sender, EventArgs e)
        {
            lstOnlyInP1.Items.Clear();
            lstOnlyInP2.Items.Clear();
            lstDifferent.Items.Clear();

            string P1Path = Path.Combine(txtOutputFolder.Text, txtProject1Name.Text);
            string P2Path = Path.Combine(txtOutputFolder.Text, txtProject2Name.Text);

            List<string> filesP1 = new List<string>();
            List<string> filesP2 = new List<string>();

            if (!Directory.Exists(P1Path + "Only\\"))
                Directory.CreateDirectory(P1Path + "Only\\");

            if (!Directory.Exists(P2Path + "Only\\"))
                Directory.CreateDirectory(P2Path + "Only\\");

            foreach (string sfile in Directory.GetFiles(P1Path))
            {
                filesP1.Add(sfile.Replace(P1Path, ""));
            }

            foreach (string sfile in Directory.GetFiles(P2Path))
            {
                filesP2.Add(sfile.Replace(P2Path, ""));
            }

            foreach (string name in filesP2)
            {
                if (filesP1.IndexOf(name) == -1)
                {
                    lstOnlyInP2.Items.Add(name);
                    File.Move(P2Path + "\\" + name, P2Path + "Only\\" + name);
                }
                else
                    if (!File.ReadLines(P1Path + "\\" + name).SequenceEqual(File.ReadLines(P2Path + "\\" + name)))
                    {
                        lstDifferent.Items.Add(name);
                    }
                    else
                    {
                        File.Delete(P1Path + "\\" + name);
                        File.Delete(P2Path + "\\" + name);
                    }
            }

            filesP1.Clear();
            filesP2.Clear();

            foreach (string sfile in Directory.GetFiles(P1Path))
            {
                filesP1.Add(sfile.Replace(P1Path, ""));
            }

            foreach (string sfile in Directory.GetFiles(P2Path))
            {
                filesP2.Add(sfile.Replace(P2Path, ""));
            }

            foreach (string name in filesP1)
            {
                if (filesP2.IndexOf(name) == -1)
                {
                    lstOnlyInP1.Items.Add(name);
                    File.Move(P1Path + "\\" + name, P1Path + "Only\\" + name);
                }
            }

            MessageBox.Show("Created delta successfully.", "Completed", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }

        private void btnFile1Open_Click(object sender, EventArgs e)
        {
            if (OpenDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtFirstProject.Text = OpenDialog.FileName;
            }
        }

        private void btnFile2Open_Click(object sender, EventArgs e)
        {
            if (OpenDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtSecondProject.Text = OpenDialog.FileName;
            }
        }

        private void btnOutpuiFolder_Click(object sender, EventArgs e)
        {
            if (FolderBrowserDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                txtOutputFolder.Text = FolderBrowserDialog.SelectedPath;
            }
        }


        private void MainForm_Load(object sender, EventArgs e)
        {
            lblHelp.Text = "This project helps a developer determine what is different between two environments\n\rthis is when you can't just sync by moving the layer.\n\r";
            lblHelp.Text += "\n\r";
            lblHelp.Text += "To use the app you should follow these steps\n\r";
            lblHelp.Text += "1. create a layer project on your first env. and export it\n\r";
            lblHelp.Text += "2. create a layer project on your second env. and export it\n\r";
            lblHelp.Text += "3. select the xpo files in the app\n\r";
            lblHelp.Text += "4. (using Split button) split the files into multiple xpo files\n\r";
            lblHelp.Text += "5. (using Compare button) determine the files that are different or only in one env.\n\r";
            lblHelp.Text += "6. take it from here and use the differences to sync the env.";
        }

        private void txtProject1Name_TextChanged(object sender, EventArgs e)
        {
            lblP1Files.Text = "Only in " + txtProject1Name.Text;
        }

        private void txtProject2Name_TextChanged(object sender, EventArgs e)
        {
            lblP2Files.Text = "Only in " + txtProject2Name.Text;
        }

        #endregion

        #region Helper methods

        private void SplitProjectFile(string fileName, string projectName)
        {
            try
            {
                if (!Directory.Exists(Path.Combine(txtOutputFolder.Text, projectName)))
                    Directory.CreateDirectory(Path.Combine(txtOutputFolder.Text, projectName));
                else
                    throw new System.Exception(string.Format("The folder {0} already exist; change the setting in order to continue.", Path.Combine(txtOutputFolder.Text, projectName)));

                int objectsNumber = 0;
                string sT = "";

                StreamReader inputFile = new StreamReader(fileName);

                string line;
                string type = "";
                string name = "";
                bool firstRun = true;

                StreamWriter outputFile = null;

                while ((line = inputFile.ReadLine()) != null)
                {
                    if (line.ToLower().IndexOf("***element: ") > -1)
                    {
                        if (!firstRun)
                        {
                            outputFile.Close();
                            if (type != "***UNKNOWN***")
                            {
                                if (name == "")
                                    File.Copy("C:\\Temp.txt", Path.Combine(txtOutputFolder.Text, projectName) + "\\" + objectsNumber.ToString(), true);
                                else
                                    File.Copy("C:\\Temp.txt", Path.Combine(txtOutputFolder.Text, projectName) + "\\" + type + "_" + name, true);
                            }
                            name = "";
                            type = "";
                            objectsNumber++;
                        }
                        else
                        {
                            firstRun = false;
                        }

                        outputFile = new StreamWriter("C:\\temp.txt", false);
                        sT = "Exportfile for AOT version 1.0 or later"; outputFile.WriteLine(sT);
                        sT = "Formatversion: 1"; outputFile.WriteLine(sT);
                        sT = ""; outputFile.WriteLine(sT);
                        outputFile.WriteLine(line);
                    }
                    else
                    {
                        if (!firstRun)
                        {
                            if (line.ToLower().IndexOf("; microsoft dynamics ax") > -1 &&
                                type == "" &&
                                line.ToLower().Trim().IndexOf("unloaded") > -1)
                            {
                                type = line.Trim().Replace("; Microsoft Dynamics AX", "").Trim();
                                if (type.IndexOf(":") > -1)
                                {
                                    name = type.Substring(type.IndexOf(":") + 1).Trim();
                                    name = name.Replace("unloaded", "").Trim();
                                    type = type.Remove(type.IndexOf(":")).Trim();
                                }
                                else
                                    type = type.Replace("unloaded", "").Trim();

                            }
                            if (line.ToLower().IndexOf("name") > -1 &&
                                name == "" &&
                                line.ToLower().Trim().IndexOf("name") == 0 &&
                                line.ToLower().Trim().IndexOf("#") > -1)
                            {
                                name = line.Trim().Replace("Name", "").Trim().Replace("#", "");
                            }

                            outputFile.WriteLine(line);
                        }
                    }
                }

                if (!firstRun)
                {
                    outputFile.Close();
                    File.Copy("C:\\Temp.txt", Path.Combine(txtOutputFolder.Text, projectName) + "\\" + objectsNumber.ToString());
                    objectsNumber++;
                }

                inputFile.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("a");
            }
        }

        #endregion
    }
}
